<style lang="scss" scoped>
.flex-end {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}
</style>

<template>
    <div class="app-container">
        <el-card class="card">
            <el-form :model="queryParams" inline>
                <el-form-item label="关键字">
                    <el-input v-model="queryParams.name" placeholder="请输入角色名称"></el-input>
                </el-form-item>
                <el-form-item label-width="15px">
                    <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
                    <el-button type="info" icon="el-icon-refresh-right" @click="handleRefresh">刷新</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card class="table">
            <div class="table-buttons">
                <el-button v-waves type="primary" icon="el-icon-plus" @click="handleShowAlert(true)">添加</el-button>
                <el-button v-waves type="danger" icon="el-icon-delete" :disabled="isForbidden" @click="handleMultipleRemove">删除</el-button>
            </div>
            <el-table v-loading="loading" :data="list" @selection-change="selectionChange" border>
                <el-table-column align="center" type="selection" />
                <el-table-column align="center" prop="sort" label="排序" width="60px" />
                <el-table-column prop="name" label="角色名称" />
                <el-table-column prop="code" label="角色编码" />
                <el-table-column align="center" label="状态" v-slot="{ row }">
                    <el-tag v-if="row.status == 1" type="success">正常</el-tag>
                    <el-tag v-else-if="row.status == 0" type="danger">禁用</el-tag>
                    <el-tag v-else type="danger">error</el-tag>
                </el-table-column>
                <el-table-column align="center" v-slot="{ row }" label="操作" width="220px">
                    <el-button type="text" icon="el-icon-position" size="small" @click="handleShowJurisdiction(row.id)">分配权限</el-button>
                    <el-button type="text" icon="el-icon-edit" size="small" @click="handleShowAlert(false, row)">编辑</el-button>
                    <el-button type="text" icon="el-icon-delete" size="small" @click="handleSingleRemove(row.id)">删除</el-button>
                </el-table-column>
            </el-table>
            <Pagination v-show="total > 0" :total="total" :page.sync="queryParams.page_number" :limit.sync="queryParams.page_size" @pagination="getList" />
        </el-card>
        <el-dialog :title="isAdd ? '新增身份' : '编辑身份'" :visible.sync="dialogVisible" top="20vh" width="500px" :before-close="closeClearFormData" destroy-on-close>
            <el-form :model="formData" label-width="100px" size="small" ref="ruleForm" :rules="rules">
                <el-form-item label="角色名称" prop="name">
                    <el-input v-model="formData.name" placeholder="请输入角色名称" />
                </el-form-item>
                <el-form-item label="角色编码" prop="code">
                    <el-input v-model="formData.code" placeholder="请输入角色编码" />
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-radio-group v-model="formData.status">
                        <el-radio :label="1">正常</el-radio>
                        <el-radio :label="0">停用</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="排序" prop="sort">
                    <el-input-number v-model="formData.sort" :min="0" placeholder="请选则排序" controls-position="right" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="closeClearFormData">取 消</el-button>
                <el-button type="primary" @click="isAdd ? submitAdd() : submitEdit()">确 定</el-button>
            </template>
        </el-dialog>
        <el-dialog title="权限分配" :visible.sync="dialogJurisdictionVisible" top="20vh" width="500px" destroy-on-close @close="menuIds = []">
            <el-tree v-loading="permissionLoading" :data="menuList" ref="treeRef" @check-change="handleCheckChange" check-strictly default-expand-all show-checkbox node-key="id" :default-checked-keys="menuIds" :props="defaultProps"></el-tree>
            <template #footer>
                <el-button @click="dialogJurisdictionVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitPermission">确 定</el-button>
            </template>
        </el-dialog>
    </div>
</template> 

<script>
import '@/assets/css/clear-card.css'
import waves from '@/directive/waves/index.js' // 水波纹指令
import Pagination from '@/components/Pagination' // 基于 el-pagination 封装的分页器
import { add, getList, edit, remove, getPermission, setPermission } from '@/api/system/role.js'
import { getList as getMenuList } from '@/api/system/menu.js'
export default {
    name: 'Role',
    components: { Pagination },
    directives: { waves },
    data() {
        return {
            // 查询参数
            queryParams: {
                // 获取当前第 n 页
                page_number: 1,
                // 每页显示 n 条数据
                page_size: 10
            },
            // 菜单列表数据
            list: [],
            // 菜单列表条数
            total: 0,
            // 数据加载中控件
            loading: true,
            // 当前弹出窗口是添加或者修改，true：添加；false：修改
            isAdd: true,
            // 表单控件
            dialogVisible: false,
            // 新增 | 编辑，数据表单
            formData: {
                sort: 0,
                status: 1
            },
            // 父菜单列表下拉框
            options: [],
            // 添加修改接口节流阀门
            throttle: true,
            // 设置表单验证规则
            rules: {
                name: [{
                    required: true, message: '请输入角色名称', trigger: ['blur', 'change']
                }],
                code: [{
                    required: true, message: '请输入角色编码', trigger: ['blur', 'change']
                }],
                sort: [{
                    required: true, message: '请选择排序', trigger: ['blur', 'change']
                }],
                status: [{
                    required: true, message: '请选择状态', trigger: ['blur', 'change']
                }]
            },
            // 已选中的 id 数组
            ids: [],
            // 当前是否禁用删除按钮，当有复选框选中时，才不禁用
            isForbidden: true,
            // 权限分配弹窗控件
            dialogJurisdictionVisible: false,
            // 菜单数据
            menuList: [],
            // 树形结构<el-tree> props 参数设置
            defaultProps: {
                children: 'children',
                label: 'name'
            },
            // 权限 form 表单收集
            permissionFormData: {
                menu_ids: []
            },
            menuIds: [],
            permissionLoading: true
        }
    },
    created() {
        this.getList()
        this.getMenuList()
    },
    watch: {
        dialogJurisdictionVisible(value) {
            if (value) {
                this.getPermission()
            }
        }
    },
    methods: {
        getPermission() {
            const { role_id } = this.permissionFormData
            this.permissionLoading = true
            getPermission(role_id).then(({ data }) => {
                this.menuIds = data
            }).finally(() => {
                this.permissionLoading = false
            })
        },
        submitPermission() {
            if (this.throttle) {
                this.throttle = false
                const form = { ...this.permissionFormData }
                setPermission(form).then(({ message }) => {
                    this.$message.success(message)
                    this.dialogJurisdictionVisible = false
                    this.getList()
                }).finally(() => {
                    this.throttle = true
                })
            }
        },
        // 弹出分配权限窗口，并且保存权限 id
        handleShowJurisdiction(role_id) {
            this.$set(this.permissionFormData, 'role_id', role_id)
            this.dialogJurisdictionVisible = true
        },
        // 收集已选中的菜单 id
        handleCheckChange() {
            const menuIds = this.$refs.treeRef.getCheckedKeys()
            this.$set(this.permissionFormData, 'menu_ids', menuIds)
        },
        // 调用删除接口
        submitRemove(ids) {
            remove(ids).then(({ message }) => {
                this.$message.success(message)
                this.getList()
            })
        },
        // 多选删除
        handleMultipleRemove() {
            this.$confirm('是否删除选中的数据', '提醒', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const ids = [...this.ids]
                this.submitRemove(ids)
            }).catch(() => {
                this.$message.info('已取消')
            })
        },
        // 单选删除
        handleSingleRemove(id) {
            this.$confirm('是否删除该条数据', '提醒', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const ids = [id]
                this.submitRemove(ids)
            }).catch(() => {
                this.$message.info('已取消')
            })
        },
        // 调用修改接口
        submitEdit() {
            this.$refs.ruleForm.validate((valid) => {
                if (valid && this.throttle) {
                    this.throttle = false
                    const form = { ...this.formData }
                    edit(form).then(({ message }) => {
                        this.$message.success(message)
                        this.getList()
                        this.closeClearFormData()
                    }).finally(() => {
                        this.throttle = true
                    })
                }
            })
        },
        // 调用添加接口
        submitAdd() {
            this.$refs.ruleForm.validate((valid) => {
                if (valid && this.throttle) {
                    this.throttle = false
                    const form = { ...this.formData }
                    add(form).then(({ message }) => {
                        this.$message.success(message)
                        this.getList()
                        this.closeClearFormData()
                    }).finally(() => {
                        this.throttle = true
                    })
                }
            })
        },
        handleShowAlert(alertTypeBool, row) {
            // 弹出弹窗层
            this.dialogVisible = true
            // 设置弹窗类型。true：添加；false：修改；
            this.isAdd = alertTypeBool
            // 如果为修改弹窗，回显字段值并渲染页面
            if (!this.isAdd) {
                this.$set(this.formData, 'id', row.id)
                this.$set(this.formData, 'name', row.name)
                this.$set(this.formData, 'sort', row.sort)
                this.$set(this.formData, 'code', row.code)
                this.$set(this.formData, 'status', row.status)
            }
        },
        // 收集选中的 ids
        selectionChange(val) {
            this.ids = val.map(item => item.id)
            this.isForbidden = Boolean(this.ids.length === 0)
        },
        // 监听搜索按钮点击事件
        handleSearch() {
            this.queryParams.page_number = 1
            this.getList()
        },
        // 监听刷新按钮点击事件
        handleRefresh() {
            this.$data.queryParams = this.$options.data().queryParams
            this.getList()
        },
        handleChangeStatus() { },
        // 关闭弹窗时，需要清楚所有的form表单的数据
        closeClearFormData() {
            this.$data.formData = this.$options.data().formData
            this.dialogVisible = false
        },
        async getMenuList() {
            const { data } = await getMenuList()
            this.menuList = data
        },
        // 获取列表信息
        async getList() {
            this.loading = true
            const query = { ...this.queryParams }
            const { data, total } = await getList(query)
            this.list = data
            this.total = total
            this.loading = false
        }
    }
}
</script>
